package br.ufrn.btest.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import br.ufrn.btest.actions.DisplayInfoAction;
import br.ufrn.btest.actions.GenerateTestsAction;
import br.ufrn.btest.actions.LoadMachineAction;
import br.ufrn.btest.criterias.CombinatorialCriterias;
import br.ufrn.btest.criterias.FunctionalCriterias;
import br.ufrn.btest.parser.Machine;

public class Application {

	
	private Machine machine;
	private JFrame frmBtest;
	private final Action openFileAction = new LoadMachineAction(this);
	private JList operationList;
	private JTable inputSpaceTable;
	private JTable characteristicsTable;
	private JTable combinations;
	private JPanel machineInfo;
	private JLabel lblCombinatorialCriteria;
	private JComboBox partitionStrategyComboBox;
	private JComboBox combinatorialCriteriaComboBox;
	private JLabel lblMachineLoaded;
	private final Action displayAction = new DisplayInfoAction(this);
	private final Action generateTestsAction = new GenerateTestsAction(this);
	private Set<String> combinationsValues;
	private int selectedOperation;
	
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Application window = new Application();
					window.frmBtest.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Application() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmBtest = new JFrame();
		frmBtest.setTitle("BETA");
		frmBtest.setBounds(100, 100, 1000, 600);
		frmBtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel controls = new JPanel();
		controls.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		frmBtest.getContentPane().add(controls, BorderLayout.NORTH);
		controls.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		lblMachineLoaded = new JLabel("Machine Loaded: <None>");
		lblMachineLoaded.setBorder(new EmptyBorder(0, 0, 0, 40));
		controls.add(lblMachineLoaded);
		
		JLabel lblFunctionalCriteria = new JLabel("Partition Strategy:");
		lblFunctionalCriteria.setHorizontalAlignment(SwingConstants.RIGHT);
		controls.add(lblFunctionalCriteria);
		
		partitionStrategyComboBox = new JComboBox();
		partitionStrategyComboBox.setModel(new DefaultComboBoxModel(FunctionalCriterias.values()));
		controls.add(partitionStrategyComboBox);
		
		lblCombinatorialCriteria = new JLabel("Combinatorial Criteria:");
		lblCombinatorialCriteria.setHorizontalAlignment(SwingConstants.RIGHT);
		controls.add(lblCombinatorialCriteria);
		
		combinatorialCriteriaComboBox = new JComboBox();
		combinatorialCriteriaComboBox.setModel(new DefaultComboBoxModel(CombinatorialCriterias.values()));
		controls.add(combinatorialCriteriaComboBox);
		
		JButton btnDisplayInfo = new JButton();
		btnDisplayInfo.setAction(displayAction);
		btnDisplayInfo.setText("Display Info");
		controls.add(btnDisplayInfo);
		
		JPanel opNavigation = new JPanel();
		opNavigation.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		frmBtest.getContentPane().add(opNavigation, BorderLayout.WEST);
		opNavigation.setLayout(new BorderLayout(0, 0));
		
		JLabel lblOperations = new JLabel("Operations:");
		lblOperations.setBorder(new EmptyBorder(5, 5, 5, 5));
		lblOperations.setHorizontalAlignment(SwingConstants.LEFT);
		opNavigation.add(lblOperations, BorderLayout.NORTH);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setPreferredSize(new Dimension(200, scrollPane.getPreferredSize().height));
		lblOperations.setLabelFor(scrollPane);
		scrollPane.setViewportBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		opNavigation.add(scrollPane);
		
		operationList = new JList();
		operationList.setValueIsAdjusting(true);
//		operationList.addListSelectionListener(new SelectOperationListener(this));
		operationList.setVisibleRowCount(1);
		operationList.setModel(new DefaultListModel());
		operationList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scrollPane.setViewportView(operationList);
		
		JPanel actions = new JPanel();
		FlowLayout flowLayout_2 = (FlowLayout) actions.getLayout();
		flowLayout_2.setAlignment(FlowLayout.TRAILING);
		actions.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		frmBtest.getContentPane().add(actions, BorderLayout.SOUTH);
		
		JButton generateTestButton = new JButton("Create Test Report");
		generateTestButton.setAction(generateTestsAction);
		generateTestButton.setText("Create Test Specification");
		generateTestButton.setHorizontalAlignment(SwingConstants.TRAILING);
		actions.add(generateTestButton);
		
		machineInfo = new JPanel();
		frmBtest.getContentPane().add(machineInfo, BorderLayout.CENTER);
		machineInfo.setLayout(new BoxLayout(machineInfo, BoxLayout.X_AXIS));
		
		JPanel inputSpacePanel = new JPanel();
		inputSpacePanel.setLayout(new BoxLayout(inputSpacePanel, BoxLayout.Y_AXIS));
		
		JScrollPane inputSpaceScroll = new JScrollPane();
		inputSpacePanel.add(inputSpaceScroll);
		
		inputSpaceTable = new JTable();
		inputSpaceScroll.setViewportView(inputSpaceTable);
		inputSpaceTable.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Input Space:"
			}
		));
		
		JScrollPane characteristicsScroll = new JScrollPane();
		inputSpacePanel.add(characteristicsScroll);
		
		characteristicsTable = new JTable();
		characteristicsScroll.setViewportView(characteristicsTable);
		characteristicsTable.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Characteristics and Blocks"
			}
		));
		
		JScrollPane combinationsScroll = new JScrollPane();
		inputSpacePanel.add(combinationsScroll);
		
		combinations = new JTable();
		combinationsScroll.setViewportView(combinations);
		combinations.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Num:", "Combinations:"
			}
		));
		TableColumn firstColumn = combinations.getColumnModel().getColumn(0);
		firstColumn.setMaxWidth(45);
		machineInfo.add(inputSpacePanel);
		
		
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.setBackground(Color.LIGHT_GRAY);
		frmBtest.setJMenuBar(menuBar);
		
		JMenu mnFile = new JMenu("File");
		mnFile.setBackground(Color.LIGHT_GRAY);
		menuBar.add(mnFile);
		
		JMenuItem mntmLoadMachine = new JMenuItem("Load Machine");
		mntmLoadMachine.setAction(openFileAction);
		mnFile.add(mntmLoadMachine);
	}

	public Machine getMachine() {
		return machine;
	}
	
	public void setMachine(Machine machine) {
		this.machine = machine;
	}
	
	public JList getOperationList() {
		return operationList;
	}
	
	public JFrame getfrmBtest() {
		return frmBtest;
	}

	public JPanel getMachineInfo() {
		return machineInfo;
	}
	
	public JTable getInputSpaceTable() {
		return inputSpaceTable;
	}

	public JTable getCharacteristicsAndBlocksTable() {
		return characteristicsTable;
	}

	public JTable getCombinationsTable() {
		return combinations;
	}

	public JComboBox getPartitionStrategy() {
		return partitionStrategyComboBox;
	}
	
	public JComboBox getCombinatorialCriteria() {
		return combinatorialCriteriaComboBox;
	}
	
	public JLabel getLabelMachineLoaded() {
		return lblMachineLoaded;
	}
	
	public void setCombinations(Set<String> combinationsValues) {
		this.combinationsValues = combinationsValues;
	}
	
	public Set<String> getCombinations() {
		return combinationsValues;
	}

	public void setSelectedOperation(int selectedOperation) {
		this.selectedOperation = selectedOperation;
	}

	public int getSelectedOperation() {
		return selectedOperation;
	}
}
